00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _matrix_hpp_
00023 #define _matrix_hpp_
00024
00025 #include <boost/scoped_ptr.hpp>
00026 #include <gridpack/parallel/distributed.hpp>
00027 #include <gridpack/utilities/uncopyable.hpp>
00028 #include <gridpack/math/matrix_implementation.hpp>
00029 #include <gridpack/math/vector.hpp>
00030 #include <gridpack/math/matrix_storage_type.hpp>
00031
00032
00033 namespace gridpack {
00034 namespace math {
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 template <typename T, typename I = int>
00048 class MatrixT
00049 : public parallel::WrappedDistributed,
00050 private utility::Uncopyable,
00051 public BaseMatrixInterface<T, I>
00052 {
00053 public:
00054
00055 typedef typename BaseMatrixInterface<T, I>::TheType TheType;
00056 typedef typename BaseMatrixInterface<T, I>::IdxType IdxType;
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 MatrixT(const parallel::Communicator& dist,
00073 const int& local_rows,
00074 const int& local_cols,
00075 const MatrixStorageType& storage_type = Sparse);
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 MatrixT(const parallel::Communicator& dist,
00093 const int& local_rows,
00094 const int& local_cols,
00095 const int& max_nz_per_row);
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 MatrixT(const parallel::Communicator& dist,
00109 const int& local_rows,
00110 const int& local_cols,
00111 const int *nz_by_row);
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 MatrixT(MatrixImplementation<T, I> *impl)
00122 : parallel::WrappedDistributed(impl),
00123 utility::Uncopyable(),
00124 p_matrix_impl(impl)
00125 {
00126 BOOST_ASSERT(p_matrix_impl);
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 ~MatrixT(void)
00136 {
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 static MatrixT *
00153 createDense(const parallel::Communicator& comm,
00154 const int& global_rows,
00155 const int& global_cols,
00156 const int& local_rows,
00157 const int& local_cols);
00158
00159
00160 MatrixStorageType storageType(void) const;
00161
00162
00163
00164
00165 void accept(ImplementationVisitor& visitor)
00166 {
00167 p_matrix_impl->accept(visitor);
00168 }
00169
00170
00171 void accept(ConstImplementationVisitor& visitor) const
00172 {
00173 p_matrix_impl->accept(visitor);
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 MatrixT *clone(void) const
00188 {
00189 MatrixImplementation<T, I> *pimpl_clone =
00190 this->p_matrix_impl->clone();
00191 MatrixT *result = new MatrixT(pimpl_clone);
00192 return result;
00193 }
00194
00195 MatrixT *localClone(void) const
00196 {
00197 MatrixImplementation<T, I> *pimpl_clone =
00198 this->p_matrix_impl->localClone();
00199 MatrixT *result = new MatrixT(pimpl_clone);
00200 return result;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void equate(const MatrixT& A);
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 void multiplyDiagonal(const VectorT<T, I>& x);
00232
00233
00234
00235
00236
00237
00238
00239 void addDiagonalVector(const VectorT<T, I>& x);
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 void add(const MatrixT& A);
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 protected:
00269
00270
00271 boost::scoped_ptr< MatrixImplementation<T, I> > p_matrix_impl;
00272
00273
00274 void p_localRowRange(IdxType& lo, IdxType& hi) const
00275 {
00276 p_matrix_impl->localRowRange(lo, hi);
00277 }
00278
00279
00280 IdxType p_rows(void) const
00281 {
00282 return p_matrix_impl->rows();
00283 }
00284
00285
00286 IdxType p_localRows(void) const
00287 {
00288 return p_matrix_impl->localRows();
00289 }
00290
00291
00292 IdxType p_cols(void) const
00293 {
00294 return p_matrix_impl->cols();
00295 }
00296
00297
00298 IdxType p_localCols(void) const
00299 {
00300 return p_matrix_impl->localCols();
00301 }
00302
00303
00304 void p_setElement(const IdxType& i, const IdxType& j, const TheType& x)
00305 {
00306 p_matrix_impl->setElement(i, j, x);
00307 }
00308
00309
00310 void p_setElements(const IdxType& n,
00311 const IdxType *i, const IdxType *j,
00312 const TheType *x)
00313 {
00314 p_matrix_impl->setElements(n, i, j, x);
00315 }
00316
00317
00318 void p_addElement(const IdxType& i, const IdxType& j, const TheType& x)
00319 {
00320 p_matrix_impl->addElement(i, j, x);
00321 }
00322
00323
00324 void p_addElements(const IdxType& n,
00325 const IdxType *i, const IdxType *j,
00326 const TheType *x)
00327 {
00328 p_matrix_impl->addElements(n, i, j, x);
00329 }
00330
00331
00332 void p_getElement(const IdxType& i, const IdxType& j, TheType& x) const
00333 {
00334 p_matrix_impl->getElement(i, j, x);
00335 }
00336
00337
00338 void p_getElements(const IdxType& n,
00339 const IdxType *i, const IdxType *j,
00340 TheType *x) const
00341 {
00342 p_matrix_impl->getElements(n, i, j, x);
00343 }
00344
00345
00346 void p_scale(const TheType& x)
00347 {
00348 p_matrix_impl->scale(x);
00349 }
00350
00351
00352 void p_addDiagonal(const TheType& x)
00353 {
00354 p_matrix_impl->addDiagonal(x);
00355 }
00356
00357
00358 void p_identity(void)
00359 {
00360 p_matrix_impl->identity();
00361 }
00362
00363
00364 void p_getRow(const IdxType& row, TheType *x) const
00365 {
00366 p_matrix_impl->getRow(row, x);
00367 }
00368
00369
00370 void p_getRowBlock(const IdxType& nrow, const IdxType *rows, TheType *x) const
00371 {
00372 p_matrix_impl->getRowBlock(nrow, rows, x);
00373 }
00374
00375
00376 void p_real(void)
00377 {
00378 p_matrix_impl->real();
00379 }
00380
00381
00382 void p_imaginary(void)
00383 {
00384 p_matrix_impl->imaginary();
00385 }
00386
00387
00388 void p_conjugate(void)
00389 {
00390 p_matrix_impl->conjugate();
00391 }
00392
00393
00394 double p_norm2(void) const
00395 {
00396 return p_matrix_impl->norm2();
00397 }
00398
00399
00400 void p_zero(void)
00401 {
00402 p_matrix_impl->zero();
00403 }
00404
00405
00406 void p_ready(void)
00407 {
00408 p_matrix_impl->ready();
00409 }
00410
00411
00412 void p_print(const char* filename = NULL) const
00413 {
00414 p_matrix_impl->print(filename);
00415 }
00416
00417
00418 void p_save(const char *filename) const
00419 {
00420 p_matrix_impl->save(filename);
00421 }
00422
00423
00424 void p_loadBinary(const char *filename)
00425 {
00426 p_matrix_impl->loadBinary(filename);
00427 }
00428
00429
00430 void p_saveBinary(const char *filename) const
00431 {
00432 p_matrix_impl->saveBinary(filename);
00433 }
00434
00435
00436 void p_accept(ImplementationVisitor& visitor)
00437 {
00438 p_matrix_impl->accept(visitor);
00439 }
00440
00441
00442 void p_accept(ConstImplementationVisitor& visitor) const
00443 {
00444 p_matrix_impl->accept(visitor);
00445 }
00446
00447
00448 void p_check_compatible(const MatrixT& A) const
00449 {
00450
00451
00452
00453
00454
00455 if ((this->rows() != A.rows()) || (this->cols() != A.cols())) {
00456 throw gridpack::Exception("incompatible: sizes do not match");
00457 }
00458 return;
00459 }
00460
00461 };
00462
00463 typedef MatrixT<ComplexType> ComplexMatrix;
00464 typedef MatrixT<RealType> RealMatrix;
00465
00466
00467 typedef ComplexMatrix Matrix;
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 template <typename T, typename I>
00479 void add(const MatrixT<T, I>& A, const MatrixT<T, I>& B, MatrixT<T, I>& result)
00480 {
00481 result.equate(A);
00482 result.add(B);
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492 template <typename T, typename I>
00493 void
00494 transpose(const MatrixT<T, I>& A, MatrixT<T, I>& result);
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 template <typename T, typename I>
00505 void
00506 column(const MatrixT<T, I>& A, const int& cidx, VectorT<T, I>& x);
00507
00508
00509
00510
00511
00512
00513
00514 template <typename T, typename I>
00515 void
00516 diagonal(const MatrixT<T, I>& A, VectorT<T, I>& x);
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 template <typename T, typename I>
00527 void
00528 multiply(const MatrixT<T, I>& A, const MatrixT<T, I>& B, MatrixT<T, I>& result);
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 template <typename T, typename I>
00542 void
00543 multiply(const MatrixT<T, I>& A, const VectorT<T, I>& x, VectorT<T, I>& result);
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 template <typename T, typename I>
00554 void
00555 transposeMultiply(const MatrixT<T, I>& A, const VectorT<T, I>& x, VectorT<T, I>& result);
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 template <typename T, typename I>
00578 MatrixT<T, I> *add(const MatrixT<T, I>& A, const MatrixT<T, I>& B)
00579 {
00580 MatrixT<T, I> *result = A.clone();
00581 add(A, B, *result);
00582 return result;
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 template <typename T, typename I>
00596 MatrixT<T, I> *transpose(const MatrixT<T, I>& A);
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 template <typename T, typename I>
00608 VectorT<T, I> *column(const MatrixT<T, I>& A, const int& cidx)
00609 {
00610 VectorT<T, I> *colv(new VectorT<T, I>(A.communicator(), A.localRows()));
00611 column<T, I>(A, cidx, *colv);
00612 return colv;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 template <typename T, typename I>
00625 VectorT<T, I> *diagonal(const MatrixT<T, I>& A)
00626 {
00627 VectorT<T, I> *colv(new VectorT<T, I>(A.communicator(), A.localRows()));
00628 diagonal<T, I>(A, *colv);
00629 return colv;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 template <typename T, typename I>
00643 MatrixT<T, I> *diagonal(const VectorT<T, I>& x,
00644 const MatrixStorageType& stype = Sparse);
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 template <typename T, typename I>
00656 MatrixT<T, I> *multiply(const MatrixT<T, I>& A, const MatrixT<T, I>& B);
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666 template <typename T, typename I>
00667 VectorT<T, I> *multiply(const MatrixT<T, I>& A, const VectorT<T, I>& x)
00668 {
00669 VectorT<T, I> *result(new VectorT<T, I>(x.communicator(), A.localRows()));
00670 multiply<T, I>(A, x, *result);
00671 return result;
00672 }
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683 template <typename T, typename I>
00684 VectorT<T, I> *transposeMultiply(const MatrixT<T, I>& A, const VectorT<T, I>& x)
00685 {
00686 VectorT<T, I> *result(new VectorT<T, I>(x.communicator(), x.localSize()));
00687 transposeMultiply<T, I>(A, x, *result);
00688 return result;
00689 }
00690
00691
00692 template <typename T, typename I>
00693 MatrixT<T, I> *identity(const MatrixT<T, I>& A)
00694 {
00695 MatrixT<T, I> *result(A.clone());
00696 result->identity();
00697 return result;
00698 }
00699
00700
00701
00702 template <typename T, typename I>
00703 MatrixT<T, I> *real(const MatrixT<T, I>& A)
00704 {
00705 MatrixT<T, I> *result = A.clone();
00706 result->real();
00707 return result;
00708 }
00709
00710
00711 template <typename T, typename I>
00712 MatrixT<T, I> *imaginary(const MatrixT<T, I>& A)
00713 {
00714 MatrixT<T, I> *result = A.clone();
00715 result->imaginary();
00716 return result;
00717 }
00718
00719
00720 template <typename T, typename I>
00721 MatrixT<T, I> *conjugate(const MatrixT<T, I>& A)
00722 {
00723 MatrixT<T, I> *result = A.clone();
00724 result->conjugate();
00725 return result;
00726 }
00727
00728
00729
00730 template <typename T, typename I>
00731 extern MatrixT<T, I> *
00732 storageType(const MatrixT<T, I>& A, const MatrixStorageType& new_type);
00733
00734
00735 template <typename T, typename I>
00736 extern MatrixT<T, I> *
00737 matrixLoadBinary(const parallel::Communicator&comm, const char *filename);
00738
00739
00740 }
00741 }
00742
00743
00744
00745 #endif